import { ModulesTree } from './modules';

const gulp = require("gulp");
const ts = require("gulp-typescript");
const sourcemaps = require('gulp-sourcemaps');
const rename = require("gulp-rename");
const uglify = require("gulp-uglify");
const concat = require('gulp-concat');
const clean = require('gulp-clean');
const jsobfuscator = require('gulp-javascript-obfuscator');
const debug = require('gulp-debug');
const notify = require('gulp-notify');
const merge = require('merge2');
const through = require('through2');
const fs = require("fs");
const path = require("path");
const yargs = require('yargs');

/**
 * 清空资源框架
 */
function cleanAssetFramework(cb) {
	if(fs.existsSync('src/framework')){
		console.log("cleanAssetFramework");
		return gulp.src([ 'assets/src/lcc-framework.js', 'lcc-framework.d.ts'], { read: false, allowEmpty:true })
			.pipe(clean({ force:true }));
	}else{
		console.error("src/framework not found!");
		cb();
	}
}

/**
 * 构建资源框架
 */
function buildAssetFramework(cb) {
	if(fs.existsSync('src/framework')){
		console.log("buildAssetFramework");
		let tsResult = gulp.src([ 'src/framework/**/*.ts', 'declarations/creator.d.ts', 'src/@types/**/*.ts', '../../temp/declarations/**/*.ts' ])
			.pipe(sourcemaps.init())
            .pipe(ts.createProject('src/framework/tsconfig.json', {
				target : "ES2015",
            })())
			.on("error",function(err:any){
				console.error(err.message);
			});
		return merge(
			tsResult.js
				.pipe(sourcemaps.write())
                .pipe(through.obj(function (chunk, enc, callback){
                    let sdata = chunk.contents.toString();
                    let jspb = fs.readFileSync('libs/protobuf.js', 'utf8');
					sdata = sdata + '\n' + jspb;
                    chunk.contents = Buffer.from(sdata);
                    this.push(chunk)
                    callback();
                }))
				.pipe(gulp.dest('assets/scripts')),
			tsResult.dts
                .pipe(through.obj(function (chunk, enc, callback){
                    let sdata = chunk.contents.toString();
                    sdata = sdata.replace(new RegExp('/// <reference types="../../../../temp', "g" ),'/// <reference types="../../temp');
                    chunk.contents = Buffer.from(sdata);
                    this.push(chunk)
                    callback();
                }))
				.pipe(gulp.dest('declarations'))
			);
	}else{
		console.error("src/framework not found!");
		cb();
	}
}

/**
 * 构建发布框架
 */
function buildPublishFramework(cb) {
	if(fs.existsSync('src/framework')){
		console.log("buildPublishFramework");
		let argv = yargs
			.default('debug', false)
			.default('confuse', false)
			.default('modules', "")
			.default('outDir', "temp")
			.default('outFile', "framework-cache.js")
			.boolean(['debug', 'confuse'])
			.argv;
        
        // 计算编译源文件
        let modulesTree = new ModulesTree('src/framework/modules.json');
        modulesTree.keepModules(argv.modules.split(','));
		let modules = modulesTree.collectModules();
        let sources = modulesTree.collectSources().map((item, index, input) => { return 'src/framework/' + item; });
        sources.push(...['declarations/creator.d.ts', 'src/@types/**/*.ts', '../../temp/declarations/**/*.ts']);
        
		let gulpState = gulp.src(sources);
		if(argv.debug){
			gulpState = gulpState.pipe(sourcemaps.init());
		}
		gulpState = gulpState.pipe(ts.createProject('src/framework/tsconfig.json', { 
			target : "ES5",
			declaration : false,
			removeComments : true,
			outFile : argv.outFile,
		})())
		.on("error",function(err:any){
			console.error(err.message);
		});
		gulpState = gulpState.js;
		if(argv.confuse){
			gulpState = gulpState.pipe(jsobfuscator({
				compact: true
			}));
		}
		gulpState = gulpState.pipe(uglify());
		if(argv.debug){
			gulpState = gulpState.pipe(sourcemaps.write());
		}
		if(modules.indexOf('network/protobuf') != -1){
			gulpState = gulpState.pipe(through.obj(function (chunk, enc, callback){
				let sdata = chunk.contents.toString();
				let jspb = fs.readFileSync('libs/protobuf.js', 'utf8');
				sdata = sdata + '\n' + jspb;
				chunk.contents = Buffer.from(sdata);
				this.push(chunk)
				callback();
			}));
		}
		return gulpState.pipe(gulp.dest(argv.outDir));
	}else{
		console.error("src/framework not found!");
		cb();
	}
}

export const buildAsset = gulp.series(cleanAssetFramework, buildAssetFramework);

export const buildPublish = buildPublishFramework;
